package dao

import (
	model3 "activity_srv/model"
	"go.uber.org/zap"
	"gorm.io/gorm"
	model2 "homepage_srv/model"
	"order_srv/model"
	"order_srv/order"
	"smart-health-platforms/config"
	"smart-health-platforms/pkg"
	"time"
)

func UpdateOrderPay(in *order.OrderUpdatePayStatusRequest) (*order.OrderUpdatePayStatusResponse, error) {
	orders := &model.Order{
		OrderSn:   in.OrderSn,
		PayStatus: uint8(in.PayStatus),
	}

	// 获取订单信息
	tx := config.DB.Begin() // 开启事务
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	if err := tx.Error; err != nil {
		return nil, err
	}

	if err := orders.UpdateOrderPay(tx); err != nil { // 更新订单支付状态
		tx.Rollback()
		return nil, err
	}
	pkg.Info("更新订单支付状态成功", zap.Any("order", orders))
	err := orders.GetByOrderOrderNo()
	if err != nil {
		pkg.Error("获取订单信息失败", zap.Error(err))
		return nil, err
	}

	var goodSku model2.GoodSku
	goodSku.Id = uint32(orders.GoodskuId)
	err = goodSku.GetByGoodId(int(goodSku.Id))
	if err != nil {
		pkg.Error("获取商品信息失败", zap.Error(err))
		return nil, err
	}

	goodSku.Stock -= orders.TotalNum // 减少商品 SKU 库存

	if err = goodSku.UpdateGoodsStock(tx); err != nil { // 更新商品 SKU 库存
		tx.Rollback()
		return nil, err
	}
	pkg.Info("更新商品库存成功", zap.Any("good_stock", goodSku.Stock))

	// 异步处理分销，避免影响主流程
	go func() {
		// 在goroutine内部创建新事务
		asyncTx := config.DB.Begin()
		defer func() {
			if r := recover(); r != nil {
				asyncTx.Rollback()
				pkg.Error("分销处理发生panic", zap.Any("recover", r))
			}
		}()
		//处理分销流水
		if err = DistributionOrder(asyncTx, orders); err != nil {
			pkg.Error("处理分销流水失败", zap.Error(err))
			asyncTx.Rollback()
			return
		}
		pkg.Info("开始查询分销流水", zap.Uint32("orderId", orders.Id))
		// 查询该订单产生的所有分销流水
		var commission model3.DistributionCommission
		commissions, err := commission.GetDistributionCommissionByOrderSn(asyncTx, orders.OrderSn)
		if err != nil {
			pkg.Error("查询订单分销流水失败", zap.Error(err))
			return
		}

		pkg.Info("查询到的分销流水", zap.Int("count", len(commissions)))

		// 按用户分组累加佣金
		userCommissionMap := make(map[uint32]float64)
		for _, comm := range commissions {
			if comm.ToUserId > 0 {
				userCommissionMap[comm.ToUserId] += comm.Amount
				pkg.Info("累加用户佣金",
					zap.Uint32("userId", comm.ToUserId),
					zap.Float64("amount", comm.Amount))
			}
		}
		// 更新每个获得佣金的用户
		for toUserId, totalAmount := range userCommissionMap {
			distributionUser := &model3.DistributionUser{
				UserId:      toUserId,
				TotalIncome: totalAmount, // 存入的总金额等于本次获得的佣金
				Frozen:      totalAmount, // 存入的冻结金额等于本次获得的佣金
			}
			// 更新总佣金
			if err = distributionUser.UpdateTotalIncome(asyncTx); err != nil {
				pkg.Error("更新用户总佣金失败", zap.Error(err), zap.Uint32("userId", toUserId))
				asyncTx.Rollback()
				return
			}
			// 更新冻结佣金
			if err = distributionUser.UpdateFrozen(asyncTx); err != nil {
				pkg.Error("更新用户冻结佣金失败", zap.Error(err), zap.Uint32("userId", toUserId))
				asyncTx.Rollback()
				return
			}
			pkg.Info("更新用户佣金成功",
				zap.Uint32("userId", toUserId),
				zap.Float64("totalAmount", totalAmount))
			// 2小时后解冻（使用正确的金额）
			ScheduleUnfreeze(int64(toUserId), totalAmount)
		}
		// 提交事务
		if err = asyncTx.Commit().Error; err != nil {
			pkg.Error("提交分销事务失败", zap.Error(err))
			return
		}
		pkg.Info("分销处理完成", zap.Int64("orderId", int64(orders.Id)))
	}()
	if err = tx.Commit().Error; err != nil {
		return nil, err
	}
	go func() {
		//修改砍价详情表
		var ba model3.BargainActivity
		ba.OrderSn = in.OrderSn
		err = ba.GetOrderSn()
		if err != nil {
			return
		}
		baID := ba.Id
		ba.Status = 4
		err = ba.UpdateBargainActivity()
		if err != nil {
			return
		}
		//添加流水表
		bas := model3.BargainWater{
			UserId:            int32(orders.UserId),
			BargainActivityId: int32(baID),
			BargainPrice:      orders.TotalPrice,
			OrderSn:           in.OrderSn,
		}
		err = bas.AddBargainWater()
		if err != nil {
			return
		}
	}()
	return &order.OrderUpdatePayStatusResponse{}, nil
}

// 设置定时任务，每2分钟，将冻结金额转换为可用金额
func ScheduleUnfreeze(userId int64, totalAmount float64) {
	time.AfterFunc(2*time.Minute, func() {
		err := config.DB.Transaction(func(tx *gorm.DB) error {
			// 查询用户当前信息
			var user model3.DistributionUser
			if err := user.GetUserByInfo(tx, userId); err != nil {
				pkg.Error("查询用户信息失败", zap.Error(err), zap.Int64("userId", userId))
				return err
			}
			// 创建更新对象，设置要操作的金额
			userToUpdate := &model3.DistributionUser{
				UserId:    uint32(userId),
				Frozen:    totalAmount, // 要减少的冻结金额
				Available: totalAmount, // 要增加的可用金额
			}
			// 更新用户冻结金额
			if err := userToUpdate.ReduceFrozen(tx); err != nil {
				pkg.Error("更新用户冻结金额失败", zap.Error(err), zap.Int64("userId", userId))
				return err
			}
			// 更新用户可用金额
			if err := userToUpdate.UpdateAvailable(tx); err != nil {
				pkg.Error("更新用户可用金额失败", zap.Error(err), zap.Int64("userId", userId))
				return err
			}
			pkg.Info("冻结金额解冻成功",
				zap.Int64("userId", userId),
				zap.Float64("amount", totalAmount))
			return nil
		})
		if err != nil {
			pkg.Error("解冻任务执行失败", zap.Error(err), zap.Int64("userId", userId))
		}
	})
	pkg.Info("已安排解冻任务2分钟后",
		zap.Int64("userId", userId),
		zap.Float64("amount", totalAmount),
		zap.Time("executeTime", time.Now().Add(2*time.Minute)))

}
